﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Sage.Caching.Memory.Options;
using Sage.Caching.Memory.Services;

namespace Sage.Caching.Memory.Extensions
{
    /// <summary>
    /// 提供与缓存相关的扩展方法。
    /// </summary>
    public static class CacheExtensions
    {
        /// <summary>
        /// 向服务集合添加内存缓存服务。
        /// </summary>
        /// <param name="services">服务集合。</param>
        /// <returns>服务集合。</returns>
        public static IServiceCollection AddMemoryCacheService(this IServiceCollection services)
        {
            // 注册默认内存缓存
            services.AddMemoryCache();

            // 注册默认选项
            services.TryAddSingleton(new MemoryCacheServiceOptions());

            // 注册缓存服务
            services.TryAddSingleton<ICacheService, MemoryCacheService>();

            return services;
        }

        /// <summary>
        /// 向服务集合添加内存缓存服务，并可以配置相关选项。
        /// </summary>
        /// <param name="services">服务集合。</param>
        /// <param name="configureOptions">配置缓存服务选项的委托。</param>
        /// <returns>服务集合。</returns>
        public static IServiceCollection AddMemoryCacheService(
            this IServiceCollection services,
            Action<MemoryCacheServiceOptions> configureOptions)
        {
            // 参数验证
            ArgumentNullException.ThrowIfNull(services);
            ArgumentNullException.ThrowIfNull(configureOptions);

            // 创建内存缓存服务配置选项实例并使用委托进行配置
            var serviceOptions = new MemoryCacheServiceOptions();
            configureOptions(serviceOptions);

            // 配置内存缓存
            services.AddMemoryCache(options =>
            {
                // 如果设置了总大小限制，则在 MemoryCacheOptions 中应用
                if (serviceOptions.MaximumCacheSize.HasValue)
                {
                    options.SizeLimit = serviceOptions.MaximumCacheSize.Value;
                }

                // 设置过期项扫描频率
                options.ExpirationScanFrequency = serviceOptions.ExpirationScanFrequency;

                // 设置压缩百分比
                options.CompactionPercentage = serviceOptions.CompactionPercentage;
            });

            // 注册 MemoryCacheServiceOptions
            services.TryAddSingleton(serviceOptions);

            // 注册缓存服务
            services.TryAddSingleton<ICacheService, MemoryCacheService>();

            return services;
        }
    }
}
